package com.answeringplayer.service.Impl;

import com.answeringplayer.Bean.Request;
import com.answeringplayer.Bean.Response;
import com.answeringplayer.domain.ExamAnswer;
import com.answeringplayer.domain.Question;
import com.answeringplayer.domain.User;
import com.answeringplayer.dto.*;
import com.answeringplayer.mapper.*;
import com.answeringplayer.service.ExamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ExamServiceImpl implements ExamService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private PracticeRecordMapper practiceRecordMapper;

    @Autowired
    private  UserMapper userMapper;
    @Autowired
    private  WrongQuestionMapper wrongQuestionMapper;
    @Autowired
    private  ExamAnswerMapper examAnswerMapper;
    @Override
    public Response<StartExamResponseDTO> startExam(Request<StartExamRequestDTO> request) {
        try {
            if (request == null || request.getData() == null) {
                return Response.error(400, "请求体不能为空");
            }

            Long userId = request.getUserId();
            StartExamRequestDTO req = request.getData();

            if (userId == null || userId <= 0) {
                return Response.error(400, "用户ID无效");
            }
            if (req.getBankId() == null || req.getBankId() <= 0) {
                return Response.error(400, "题库ID不能为空");
            }

            int limit = (req.getLimit() == null || req.getLimit() <= 0) ? 20 : req.getLimit();

            // 查询题库题目
            List<Question> allQuestions = questionMapper.selectByBankId(req.getBankId());
            if (allQuestions == null || allQuestions.isEmpty()) {
                return Response.error(404, "该题库暂无试题");
            }

            // 可选过滤：题型和难度
            List<Question> filtered = allQuestions.stream()
                    .filter(q -> req.getQuestionType() == null || Objects.equals(q.getQuestionType(), req.getQuestionType()))
                    .filter(q -> req.getDifficulty() == null || Objects.equals(q.getDifficulty(), req.getDifficulty()))
                    .collect(Collectors.toList());

            if (filtered.isEmpty()) {
                return Response.error(404, "没有匹配筛选条件的试题");
            }

            // 随机抽取limit道题
            Collections.shuffle(filtered);
            List<Question> selected = filtered.subList(0, Math.min(limit, filtered.size()));

            // 写入练习记录（开始考试）
            PracticeRecordDTO record = new PracticeRecordDTO();
            record.setUserId(userId);
            record.setPracticeType(PracticeRecordDTO.PracticeType.EXAM);
            record.setBankId(req.getBankId());
            record.setScore(0);
            record.setTotalQuestions(selected.size());
            record.setCorrectCount(0);
            record.setStartTime(LocalDateTime.now());
            record.setEndTime(null);
            practiceRecordMapper.insert(record);

            // 转换题目为响应DTO（剔除正确答案）
            List<StartExamQuestionDTO> questionDTOs = new ArrayList<>(selected.size());
            for (Question q : selected) {
                StartExamQuestionDTO dto = new StartExamQuestionDTO();
                dto.setQuestionId(q.getQuestionId());
                dto.setBankId(q.getBankId());
                dto.setQuestionType(q.getQuestionType());
                dto.setContent(q.getContent());
                dto.setOptions(q.getOptions());
                dto.setDifficulty(q.getDifficulty());
                questionDTOs.add(dto);
            }

            // 构造响应
            StartExamResponseDTO resp = new StartExamResponseDTO();
            resp.setRecordId(record.getRecordId());
            resp.setTotalQuestions(record.getTotalQuestions());
            resp.setStartTime(record.getStartTime());
            resp.setBankId(req.getBankId());
            resp.setQuestions(questionDTOs);

            return Response.success("考试已开始", resp);
        } catch (Exception e) {
            return Response.error(500, "开始考试失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Response<SubmitAnswerResponse> submitAnswer(
            Long userId,
            Integer bankId,
            String practiceType,
            List<AnswerDTO> answers
    ) {
        try {
            // 参数验证
            if (userId == null || answers == null || answers.isEmpty()) {
                return Response.error(400, "参数错误");
            }

            // 验证用户是否存在
            User user = userMapper.selectById(userId);
            if (user == null) {
                return Response.error(404, "用户不存在");
            }

            List<AnswerResultDTO> results = new ArrayList<>();
            int correctCount = 0;
            int totalQuestions = answers.size();

            // 处理每道题的答案
            for (AnswerDTO answer : answers) {
                AnswerResultDTO result = processSingleAnswer(answer);
                results.add(result);

                if (result.getIsCorrect()) {
                    correctCount++;
                } else {
                    // 答错的题目记录到错题本
                    handleWrongQuestion(userId, answer.getQuestionId());
                }

                // 记录答题详情
                saveExamAnswer(userId, answer, result.getIsCorrect());
            }

            // 计算分数（百分比）
            int score = (correctCount * 100) / totalQuestions;

            // 保存练习记录
            Long recordId = savePracticeRecord(userId, practiceType, bankId, score, totalQuestions, correctCount);

            // 更新用户统计信息
            updateUserStatistics(userId, totalQuestions, correctCount);

            // 构建响应
            SubmitAnswerResponse response = new SubmitAnswerResponse();
            response.setTotalQuestions(totalQuestions);
            response.setCorrectCount(correctCount);
            response.setScore(score);
            response.setAccuracy((double) correctCount / totalQuestions);
            response.setResults(results);

            return Response.success("提交成功", response);

        } catch (Exception e) {
            return Response.error(500, "提交失败: " + e.getMessage());
        }
    }

    @Override
    public Response<List<PracticeRecordDTO>> getPracticeRecords(Long userId) {
        try {
            List<PracticeRecordDTO> records = practiceRecordMapper.selectByUserId(userId);
            return Response.success(records);
        } catch (Exception e) {
            return Response.error(500, "获取练习记录失败: " + e.getMessage());
        }
    }

    /**
     * 处理单个题目的答案
     */
    private AnswerResultDTO processSingleAnswer(AnswerDTO answer) {
        Question question = questionMapper.selectById(answer.getQuestionId());
        if (question == null) {
            throw new RuntimeException("题目不存在: " + answer.getQuestionId());
        }

        AnswerResultDTO result = new AnswerResultDTO();
        result.setQuestionId(answer.getQuestionId());
        result.setCorrectAnswer(question.getCorrectAnswer());
        result.setUserAnswer(answer.getUserAnswer());
        result.setAnalysis(question.getAnalysis());

        // 根据题型进行答案判断
        boolean isCorrect = checkAnswerByType(
                answer.getUserAnswer(),
                question.getCorrectAnswer(),
                answer.getQuestionType()
        );

        result.setIsCorrect(isCorrect);
        return result;
    }

    /**
     * 根据题型判断答案是否正确
     */
    private boolean checkAnswerByType(String userAnswer, String correctAnswer, String questionType) {
        if (userAnswer == null || correctAnswer == null) {
            return false;
        }

        switch (questionType) {
            case "SINGLE":
                // 单选题：直接比较（忽略大小写和空格）
                return userAnswer.trim().equalsIgnoreCase(correctAnswer.trim());

            case "MULTIPLE":
                // 多选题：需要所有选项都正确且顺序无关
                return checkMultipleChoiceAnswer(userAnswer, correctAnswer);

            case "TRUE_FALSE":
                // 判断题：比较布尔值
                return checkTrueFalseAnswer(userAnswer, correctAnswer);

            case "FILL_IN":
                // 填空题：允许部分匹配（关键词匹配）
                return checkFillInAnswer(userAnswer, correctAnswer);

            default:
                return false;
        }
    }

    /**
     * 多选题答案检查（顺序无关）
     */
    private boolean checkMultipleChoiceAnswer(String userAnswer, String correctAnswer) {
        // 假设答案格式为 "A,B,C" 或 "ABC"
        String normalizedUser = normalizeMultipleChoice(userAnswer);
        String normalizedCorrect = normalizeMultipleChoice(correctAnswer);
        return normalizedUser.equals(normalizedCorrect);
    }

    private String normalizeMultipleChoice(String answer) {
        // 移除空格，按字母排序
        String cleaned = answer.replaceAll("[^A-Z]", "").toUpperCase();
        char[] chars = cleaned.toCharArray();
        java.util.Arrays.sort(chars);
        return new String(chars);
    }

    /**
     * 判断题答案检查
     */
    private boolean checkTrueFalseAnswer(String userAnswer, String correctAnswer) {
        String user = userAnswer.trim().toLowerCase();
        String correct = correctAnswer.trim().toLowerCase();

        // 支持多种表示方式
        if (user.equals("true") || user.equals("正确") || user.equals("对") || user.equals("1")) {
            user = "true";
        } else if (user.equals("false") || user.equals("错误") || user.equals("错") || user.equals("0")) {
            user = "false";
        }

        return user.equals(correct);
    }

    /**
     * 填空题答案检查（关键词匹配）
     */
    private boolean checkFillInAnswer(String userAnswer, String correctAnswer) {
        // 简单的包含检查，实际项目中可能需要更复杂的自然语言处理
        String user = userAnswer.trim().toLowerCase();
        String correct = correctAnswer.trim().toLowerCase();
        return user.contains(correct) || correct.contains(user);
    }

    /**
     * 处理错题逻辑
     */
    private void handleWrongQuestion(Long userId, Long questionId) {
        try {
            // 检查是否已经存在错题记录
            WrongQuestionDTO existing = wrongQuestionMapper.selectByUserAndQuestion(userId, questionId);

            if (existing != null) {
                // 更新错误次数
                existing.setWrongCount(existing.getWrongCount() + 1);
                existing.setLastWrongTime(Timestamp.valueOf(LocalDateTime.now()).toLocalDateTime());
                existing.setIsMastered(false); // 重新标记为未掌握
                wrongQuestionMapper.update(existing);
            } else {
                // 创建新的错题记录
                WrongQuestionDTO wrongQuestion = new WrongQuestionDTO();
                wrongQuestion.setUserId(userId);
                wrongQuestion.setQuestionId(questionId);
                wrongQuestion.setWrongCount(1);
                wrongQuestion.setIsMastered(false);
                wrongQuestionMapper.insert(wrongQuestion);
            }
        } catch (Exception e) {
            // 错题记录失败不影响主流程
            System.err.println("记录错题失败: " + e.getMessage());
        }
    }

    /**
     * 保存答题详情
     */
    private void saveExamAnswer(Long userId, AnswerDTO answer, Boolean isCorrect) {
        try {
            ExamAnswer examAnswer = new ExamAnswer();
            examAnswer.setUserId(userId);
            examAnswer.setQuestionId(answer.getQuestionId());
            examAnswer.setUserAnswer(answer.getUserAnswer());
            examAnswer.setIsCorrect(isCorrect);
            examAnswer.setScore(isCorrect ? 10 : 0); // 每题10分
            examAnswer.setAnsweredTime(java.sql.Timestamp.valueOf(LocalDateTime.now()));

            examAnswerMapper.insert(examAnswer);
        } catch (Exception e) {
            System.err.println("保存答题详情失败: " + e.getMessage());
        }
    }

    /**
     * 保存练习记录
     */
    private Long savePracticeRecord(Long userId, String practiceType, Integer bankId,
                                    Integer score, Integer totalQuestions, Integer correctCount) {
        PracticeRecordDTO record = new PracticeRecordDTO();
        record.setUserId(userId);
        record.setPracticeType(PracticeRecordDTO.PracticeType.valueOf(practiceType));
        record.setBankId(bankId);
        record.setScore(score);
        record.setTotalQuestions(totalQuestions);
        record.setCorrectCount(correctCount);
        record.setStartTime(Timestamp.valueOf(LocalDateTime.now().minusMinutes(30)).toLocalDateTime()); // 假设练习了30分钟
        record.setEndTime(Timestamp.valueOf(LocalDateTime.now()).toLocalDateTime());

        practiceRecordMapper.insert(record);
        return record.getRecordId();
    }

    /**
     * 更新用户统计信息
     */
    private void updateUserStatistics(Long userId, Integer totalQuestions, Integer correctCount) {
        try {
            User user = userMapper.selectById(userId);
            if (user != null) {
                // 更新总答题数和正确题数
                user.setTotalQuestionsAnswered(user.getTotalQuestionsAnswered() + totalQuestions);
                user.setCorrectQuestions(user.getCorrectQuestions() + correctCount);

                // 更新分数（简单的累加）
                user.setScore(user.getScore() + (correctCount * 10));

                // 更新连续天数（这里简化处理，实际应该检查上次答题时间）
                user.setConsecutiveDays(user.getConsecutiveDays() + 1);

                userMapper.update(user);
            }
        } catch (Exception e) {
            System.err.println("更新用户统计信息失败: " + e.getMessage());
        }
    }
}